package org.abc.fund.controller.factorController;

import org.abc.fund.entity.factorEntity.StyleFactor;
import org.abc.fund.entity.factorEntity.StyleFactorDto;
import org.abc.fund.service.factorService.StyleFactorService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * 风格因子管理Controller
 */
@RestController
@RequestMapping("/style")
@CrossOrigin

public class StyleFactorController {
    private static final Logger log = LoggerFactory.getLogger(StyleFactorController.class);
    private final StyleFactorService styleFactorService;
    private final DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");

    @Autowired
    public StyleFactorController(StyleFactorService styleFactorService) {
        this.styleFactorService = styleFactorService;
    }

    /**
     * 获取所有风格因子（不分页）
     */
    @GetMapping("/style-factor/noPage")
    public ResponseEntity<List<StyleFactor>> getAllStyleFactors() {
        try {
            List<StyleFactor> factors = styleFactorService.getAllStyleFactors(null);
            return ResponseEntity.ok(factors);
        } catch (Exception e) {
            log.error("获取风格因子列表失败", e);
            return ResponseEntity.internalServerError().build();
        }
    }

    /**
     * 创建风格因子
     */
    @PostMapping("/create/styleFactor")
    public ResponseEntity<?> create(@RequestBody StyleFactorDto dto) {
        try {
            // 验证必填字段
            if (dto.getName() == null || dto.getName().trim().isEmpty()) {
                return ResponseEntity.badRequest().body(Map.of("error", "因子名称不能为空"));
            }
            if (dto.getFactorCode() == null || dto.getFactorCode().trim().isEmpty()) {
                return ResponseEntity.badRequest().body(Map.of("error", "因子代码不能为空"));
            }
            if (dto.getFactorType() == null) {
                return ResponseEntity.badRequest().body(Map.of("error", "风格类型不能为空"));
            }
            if (dto.getAlgorithm() == null || dto.getAlgorithm().trim().isEmpty()) {
                return ResponseEntity.badRequest().body(Map.of("error", "算法不能为空"));
            }
            if (dto.getAlgorithmParams() == null || dto.getAlgorithmParams().trim().isEmpty()) {
                return ResponseEntity.badRequest().body(Map.of("error", "算法参数不能为空"));
            }
            if (dto.getBaseFactors() == null || dto.getBaseFactors().isEmpty()) {
                return ResponseEntity.badRequest().body(Map.of("error", "基础因子不能为空"));
            }
            if (dto.getWeightsConfig() == null || dto.getWeightsConfig().trim().isEmpty()) {
                return ResponseEntity.badRequest().body(Map.of("error", "权重配置不能为空"));
            }

            StyleFactor createdFactor = styleFactorService.createStyleFactor(dto);
            if (createdFactor != null) {
                return ResponseEntity.ok(createdFactor);
            } else {
                return ResponseEntity.badRequest().body(Map.of("error", "创建风格因子失败"));
            }
        } catch (IllegalArgumentException e) {
            log.warn("创建风格因子参数错误: {}", e.getMessage());
            return ResponseEntity.badRequest().body(Map.of("error", e.getMessage()));
        } catch (Exception e) {
            log.error("创建风格因子失败", e);
            return ResponseEntity.internalServerError().body(Map.of("error", "服务器内部错误"));
        }
    }

    /**
     * 更新风格因子
     */
    @PutMapping("/upData/styleFactor")
    public ResponseEntity<?> update(@RequestBody StyleFactorDto styleFactorDto) {
        try {
            if (styleFactorDto.getFactorCode() == null || styleFactorDto.getFactorCode().trim().isEmpty()) {
                return ResponseEntity.badRequest().body(Map.of("error", "因子代码不能为空"));
            }

            StyleFactor updatedFactor = styleFactorService.updateStyleFactor(styleFactorDto.getFactorCode(), styleFactorDto);
            if (updatedFactor != null) {
                return ResponseEntity.ok(updatedFactor);
            } else {
                return ResponseEntity.badRequest().body(Map.of("error", "更新风格因子失败"));
            }
        } catch (IllegalArgumentException e) {
            log.warn("更新风格因子参数错误: {}", e.getMessage());
            return ResponseEntity.badRequest().body(Map.of("error", e.getMessage()));
        } catch (Exception e) {
            log.error("更新风格因子失败", e);
            return ResponseEntity.internalServerError().body(Map.of("error", "服务器内部错误"));
        }
    }

    /**
     * 删除风格因子
     */
    @DeleteMapping("/Style/deleteById/{id}")
    public ResponseEntity<?> deleteStyleFactor(@PathVariable Long id) {
        boolean deleted = styleFactorService.deleteStyleFactorById(id);
        if (deleted) {
            return ResponseEntity.ok(Map.of("success", true, "message", "删除成功"));
        } else {
            return ResponseEntity.status(404).body(Map.of("success", false, "message", "未找到该风格因子"));
        }
    }

    /**
     * 根据ID查找风格因子
     */
    @GetMapping("/{id}")
    public ResponseEntity<?> findById(@PathVariable Long id) {
        try {
            Optional<StyleFactor> factor = styleFactorService.findById(id);
            return factor.map(ResponseEntity::ok)
                    .orElseGet(() -> ResponseEntity.notFound().build());
        } catch (Exception e) {
            log.error("查找风格因子失败", e);
            return ResponseEntity.internalServerError().body(Map.of("error", "服务器内部错误"));
        }
    }

    /**
     * 分页查询风格因子
     */
    @GetMapping("/style-factor/page")
    public Page<StyleFactor> page(
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size,
            @RequestParam(required = false) String styleType,
            @RequestParam(required = false) Boolean enabled
    ) {
        Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "updateTime"));
        return styleFactorService.findStyleFactors(styleType, enabled, pageable);
    }

    /**
     * 多条件搜索风格因子
     */
    @GetMapping("/search")
    public ResponseEntity<?> search(
            @RequestParam(required = false) String name,
            @RequestParam(required = false) String code,
            @RequestParam(required = false) StyleFactor.StyleType styleType,
            @RequestParam(required = false) String algorithm,
            @RequestParam(required = false) Boolean enabled,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size) {
        try {
            Pageable pageable = PageRequest.of(page, size);
            Page<StyleFactor> result = styleFactorService.searchStyleFactors(name, code, styleType, algorithm, enabled, pageable);
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            log.error("搜索风格因子失败", e);
            return ResponseEntity.internalServerError().body(Map.of("error", "服务器内部错误"));
        }
    }

    /**
     * 模糊查询因子名称
     */
    @GetMapping("/searchByName")
    public ResponseEntity<?> searchByName(@RequestParam String name) {
        try {
            if (name == null || name.trim().isEmpty()) {
                return ResponseEntity.badRequest().body(Map.of("error", "搜索名称不能为空"));
            }
            List<StyleFactor> result = styleFactorService.findByFactorNameContaining(name);
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            log.error("按名称搜索风格因子失败", e);
            return ResponseEntity.internalServerError().body(Map.of("error", "服务器内部错误"));
        }
    }

    /**
     * 模糊查询因子代码
     */
    @GetMapping("/searchByCode")
    public ResponseEntity<?> searchByCode(@RequestParam String code) {
        try {
            if (code == null || code.trim().isEmpty()) {
                return ResponseEntity.badRequest().body(Map.of("error", "搜索代码不能为空"));
            }
            List<StyleFactor> result = styleFactorService.findByFactorCodeContaining(code);
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            log.error("按代码搜索风格因子失败", e);
            return ResponseEntity.internalServerError().body(Map.of("error", "服务器内部错误"));
        }
    }

    /**
     * 启用/禁用风格因子
     */
    @PatchMapping("/{id}/status")
    public ResponseEntity<?> toggleStatus(
            @PathVariable Long id,
            @RequestParam Boolean enabled) {
        try {
            if (enabled == null) {
                return ResponseEntity.badRequest().body(Map.of("error", "状态参数不能为空"));
            }
            StyleFactor result = styleFactorService.toggleStyleFactorStatus(id, enabled);
            return ResponseEntity.ok(result);
        } catch (IllegalArgumentException e) {
            log.warn("切换风格因子状态参数错误: {}", e.getMessage());
            return ResponseEntity.badRequest().body(Map.of("error", e.getMessage()));
        } catch (Exception e) {
            log.error("切换风格因子状态失败", e);
            return ResponseEntity.internalServerError().body(Map.of("error", "服务器内部错误"));
        }
    }

    /**
     * 检查因子代码是否存在
     */
    @GetMapping("/exists")
    public ResponseEntity<?> existsByCode(@RequestParam String factorCode) {
        try {
            if (factorCode == null || factorCode.trim().isEmpty()) {
                return ResponseEntity.badRequest().body(Map.of("error", "因子代码不能为空"));
            }
            boolean exists = styleFactorService.existsByFactorCode(factorCode);
            return ResponseEntity.ok(exists);
        } catch (Exception e) {
            log.error("检查因子代码存在性失败", e);
            return ResponseEntity.internalServerError().body(Map.of("error", "服务器内部错误"));
        }
    }

    /**
     * 验证风格因子公式
     */
    @GetMapping("/validate")
    public ResponseEntity<?> validate(@RequestParam String formula) {
        try {
            if (formula == null || formula.trim().isEmpty()) {
                return ResponseEntity.badRequest().body(Map.of("error", "公式不能为空"));
            }
            boolean isValid = styleFactorService.validateFormula(formula);
            return ResponseEntity.ok(isValid);
        } catch (Exception e) {
            log.error("验证风格因子公式失败", e);
            return ResponseEntity.internalServerError().body(Map.of("error", "服务器内部错误"));
        }
    }

    /**
     * 计算风格因子值
     */
    @PostMapping("/{factorCode}/{fundCode}/calculate")
    public ResponseEntity<?> calculate(
            @PathVariable String factorCode,
            @PathVariable String fundCode) {
        try {
            if (factorCode == null || factorCode.trim().isEmpty()) {
                return ResponseEntity.badRequest().body(Map.of("error", "因子代码不能为空"));
            }
            if (fundCode == null || fundCode.trim().isEmpty()) {
                return ResponseEntity.badRequest().body(Map.of("error", "基金代码不能为空"));
            }

            BigDecimal value = styleFactorService.calculateStyleFactorValue(factorCode, fundCode);
            Map<String, Object> result = new HashMap<>();
            result.put("styleFactorCode", factorCode);
            result.put("fundCode", fundCode);
            result.put("factorValue", value);
            result.put("success", true);
            return ResponseEntity.ok(result);
        } catch (IllegalArgumentException e) {
            log.warn("计算风格因子值参数错误: {}", e.getMessage());
            Map<String, Object> error = Map.of(
                    "styleFactorCode", factorCode,
                    "success", false,
                    "message", e.getMessage()
            );
            return ResponseEntity.badRequest().body(error);
        } catch (Exception e) {
            log.error("计算风格因子值失败", e);
            Map<String, Object> error = Map.of(
                    "styleFactorCode", factorCode,
                    "success", false,
                    "message", "服务器内部错误"
            );
            return ResponseEntity.internalServerError().body(error);
        }
    }

    /**
     * 保存风格因子计算结果
     */
    @PostMapping("/style-factor/save-calculation-result")
    public ResponseEntity<?> saveCalculationResult(@RequestBody Map<String, Object> request) {
        try {
            String factorCode = (String) request.get("factorCode");
            String fundCode = (String) request.get("fundCode");
            Object factorValueObj = request.get("factorValue");

            if (factorCode == null || factorCode.trim().isEmpty()) {
                return ResponseEntity.badRequest().body(Map.of(
                        "success", false,
                        "message", "因子代码不能为空"
                ));
            }

            if (fundCode == null || fundCode.trim().isEmpty()) {
                return ResponseEntity.badRequest().body(Map.of(
                        "success", false,
                        "message", "基金代码不能为空"
                ));
            }

            if (factorValueObj == null) {
                return ResponseEntity.badRequest().body(Map.of(
                        "success", false,
                        "message", "因子值不能为空"
                ));
            }

            BigDecimal factorValue;
            if (factorValueObj instanceof Number) {
                factorValue = new BigDecimal(factorValueObj.toString());
            } else if (factorValueObj instanceof String) {
                factorValue = new BigDecimal((String) factorValueObj);
            } else {
                return ResponseEntity.badRequest().body(Map.of(
                        "success", false,
                        "message", "因子值格式错误"
                ));
            }

            log.info("保存风格因子计算结果: 因子={}, 基金={}, 值={}", factorCode, fundCode, factorValue);

            // 调用服务保存计算结果
            styleFactorService.saveCalculationResult(factorCode, fundCode, factorValue);

            return ResponseEntity.ok(Map.of(
                    "success", true,
                    "message", "计算结果保存成功",
                    "factorCode", factorCode,
                    "fundCode", fundCode,
                    "factorValue", factorValue
            ));

        } catch (NumberFormatException e) {
            log.warn("保存计算结果参数错误: {}", e.getMessage());
            return ResponseEntity.badRequest().body(Map.of(
                    "success", false,
                    "message", "因子值格式错误"
            ));
        } catch (Exception e) {
            log.error("保存风格因子计算结果失败", e);
            return ResponseEntity.internalServerError().body(Map.of(
                    "success", false,
                    "message", "保存失败: " + e.getMessage()
            ));
        }
    }
}
